This document is an attempt to document the AutoDesk 3DS file format. This was made difficult in that I don't own or have access to a copy of the program, only
to sample files. Fortunately, someone used AutoDesk's own 3DS file development kit to create a program which dumps the contents of a 3DS file into a human
readable form - albeit somewhat inaccurately. The codes listed and their names come from that program and have been confirmed by testing.
It should be known that the 3DS format is, as far as I know, a proprietary format of AutoDesk and that the format details are not widely known or are protected
by AutoDesk.
It is not my intent to infringe on AutoDesk's rights, but simply to make a large collection of 3D image files accessable to people who do not use 3D Studio - or
cannot use it because AutoDesk has not chosen to provide a version of 3D Studio for the computer they use (ie: The Macintosh in my case).
Warning
This document is not intended to be a definitive definition of the 3DS format and is not authorised by AutoDesk. While every effort has been made to ensure its
accuracy, or at least warn you when there's doubt about its accuracy, no guarantee of accuracy in any of it can be given. Use this document at your own risk.
Document layout and format information
In the following document, chunk names which are in bold mean the chunk format has been determined with certainty. Chunk names which are not bold but have a
struct following means that this is a guess but is not substantiated. All others are unknown.
A short is always a two byte integer.
A long is always a four byte integer.
A float is always a four byte IEEE floating point number.
A cstr is a zero byte terminated ASCII string without a length.
A char is a single byte integer.
3DS File Format
A 3DS file consists of blocks of data called chunks. Every chunk starts the same way:
short chunk_id;
long chunk_len;
The chunk_id is a unique code which identifies the type of data in this chunk and also may indicate the existence of subordinate chunks. The chunk_len indicates
the length of following data to be associated with this chunk. Note, this may contain more data than just this chunk. If the length of data is greater than that needed
to fill in the information for the chunk, additional subordinate chunks are attached to this chunk immediately following any data needed for this chunk, and should be
parsed out. These subordinate chunks may themselves contain subordinate chunks.
Unfortunately, there is no indication of the length of data which is owned by the current chunk, only the total length of data attached to the chunk, which means that
the only way to parse out subordinate chunks is to know the exact format of the owning chunk. On the other hand, if a chunk is unknown, the parsing program can
skip the entire chunk and subordinate chunks in one jump.
In the following list, I try when possible to indicate that a chunk is likely to have subordinate chunks and what kinds of subordinate chunks I've seen attached to it.
Another problem lies in cstr names. I've seen cases where the space used by a name is riddled with fragments of old names. It seems that the space reserved for a
name is not cleared if a smaller name replaces it. If the name is removed, you'll get a zero byte indicating an immediate end of string, followed by an undetermined
number of characters and nulls. This seems to happen only when the cstr is at the end of a block of data and so you can assume that the length of the chunk
contains no other subchunks. See viewport_data for an example of this.
0xxxH Group
0000H
NULL_CHUNK
0001H
Unknown chunk
float ???
0002H
M3D_VERSION
short version;
0005H
M3D_KFVERSION
0010H
COLOR_F
float red, grn, blu;
0011H
COLOR_24
char red, grn, blu;
0012H
LIN_COLOR_24
char red, grn, blu;
0013H
LIN_COLOR_F
float red, grn, blu;
0030H
INT_PERCENTAGE
short percentage;
0031H
FLOAT_PERCENTAGE
float percentage;
0100H
MASTER_SCALE
float scale;
0995H
ChunkType
0996H
ChunkUnique
0997H
NotChunk
0998H
Container
0999H
IsChunk
0c3cH
C_SXP_SELFI_MASKDATA
1xxxH Group
1100H
BIT_MAP
cstr filename;
1101H
USE_BIT_MAP
1200H
SOLID_BGND; followed by color_f
1201H
USE_SOLID_BGND
1300H
V_GRADIENT; followed by three color_f: start, mid, end
float midpoint;
1301H
USE_V_GRADIENT
1400H
LO_SHADOW_BIAS
float bias;
1410H
HI_SHADOW_BIAS
1420H
SHADOW_MAP_SIZE
short size;
1430H
SHADOW_SAMPLES
1440H
SHADOW_RANGE
1450H
SHADOW_FILTER
float filter;
1460H
RAY_BIAS
float bias;
1500H
O_CONSTS
float plane_x, plane_y, plane_z;
2xxxH Group
2100H
AMBIENT_LIGHT
2200H
FOG; followed by color_f, fog_bgnd
float near_plane, near_density;
float far_plane, far_density;
2201H
USE_FOG
2210H
FOG_BGND
2300H
DISTANCE_CUE followed by dcue_bgnd
float near_plane, near_density;
float far_plane, far_density;
2301H
USE_DISTANCE_CUE
2302H
LAYER_FOG
float fog_z_from, fog_z_to;
float fog_density;
short fog_type;
2303H
USE_LAYER_FOG
2310H
DCUE_BGND
2d2dH
SMAGIC
2d3dH
LMAGIC
3xxxH Group
3000H
DEFAULT_VIEW
3010H
VIEW_TOP
float targe_x, target_y, target_z;
float view_width;
3020H
VIEW_BOTTOM
float targe_x, target_y, target_z;
float view_width;
3030H
VIEW_LEFT
float targe_x, target_y, target_z;
float view_width;
3040H
VIEW_RIGHT
float targe_x, target_y, target_z;
float view_width;
3050H
VIEW_FRONT
float targe_x, target_y, target_z;
float view_width;
3060H
VIEW_BACK
float targe_x, target_y, target_z;
float view_width;
3070H
VIEW_USER
float targe_x, target_y, target_z;
float view_width;
3080H
VIEW_CAMERA
cstr camera_name;
3090H
VIEW_WINDOW
3d3dH
MDATA; Mesh Data Magic Number (.3DS files sub of 4d4d)
3d3eH
MESH_VERSION
3daaH
MLIBMAGIC; Material Library Magic Number (.MLI files)
3dc2H
PRJMAGIC; 3dS Project Magic Number (.PRJ files)
3dffH
MATMAGIC; Material File Magic Number (.MAT files)
4xxxH Group
4000H
NAMED_OBJECT
cstr name;
4010H
OBJ_HIDDEN
4011H
OBJ_VIS_LOFTER
4012H
OBJ_DOESNT_CAST
4013H
OBJ_MATTE
4014H
OBJ_FAST
4015H
OBJ_PROCEDURAL
4016H
OBJ_FROZEN
4017H
OBJ_DONT_RCVSHADOW
4100H
N_TRI_OBJECT
named triangle object
followed by point_array, point_flag_array, mesh_matrix,
face_array
4110H
POINT_ARRAY
short npoints;
struct {
float x, y, z;
} points[npoints];
4111H
POINT_FLAG_ARRAY
short nflags;
short flags[nflags];
4120H
FACE_ARRAY may be followed by smooth_group
short nfaces;
struct {
short vertex1, vertex2, vertex3;
short flags;
} facearray[nfaces];
4130H
MSH_MAT_GROUP mesh_material_group
cstr material_name;
short nfaces;
short facenum[nfaces];
4131H
OLD_MAT_GROUP
4140H
TEX_VERTS
short nverts;
struct {
float x, y;
} vertices[nverts];
4150H
SMOOTH_GROUP
short grouplist[n]; determined by length, seems to be 4 per face